
FROM	StdParts.Misc	  IMPORT $BDTFF, $SLatch, $Sink, $SDTFF, $SMux
FROM	StdParts.Gates	  IMPORT $SGate1, $SGate2, $SGate3, $SGate4
FROM	StdParts.PLAs	  IMPORT $PLA
FROM    StdParts.TriDrive IMPORT $SBuff
FROM	iomd.kbdc	  IMPORT $KBDC

BLOCK KBD(
 {IN} test[2:0],
 {IN} reset,
 {IN} clk,
 {IN} kclkin,
 {IN} kdatain,
 {IN} kcon_rd,
 {IN} kcon_wt,
 {IN} kdata_rd,
 {IN} kdata_wt,
 {IO} data[7:0],
 {OUT} Nkclkoe,
 {OUT} Nkdataoe,
 {OUT} ktxint,
 {OUT} krxint)

k1 = $KBDC(enable,test[0],test[1],reset,clk,sclkin,krxint,ktxint,cclkoe,cdataoe,dataoe) =>
          (t16,Nkclkoe,Nkdataoe,rxb,txb,srx,stx,st[7:0],ccnt[3:0],nostx)

s1 = $Sink(st[7:0])
s2 = $Sink(ccnt[3:0])
s3 = $Sink(rest(Nclkin,Ndatain,Nsdatain,Ncclkoe,Ncdataoe,Ndataoe,ship[0],Nsclkin))
s4 = $Sink(Nship[10:0])
s5 = $Sink(Nshop[9:0])
s6 = $Sink(rest2(nostx,Ntxint,Nstxint,Nrxint,Nsrxint))
s7 = $Sink(Nsz[7:0])

!------------------ synchronise clock and data ----------------------------

ci  = $SGate1(clk) => Nclk WITH (delay=ns_1,OP=INV)
sy1 = $SDTFF(Nclk, kclkin,VDD,VDD) => (  clkin, Nclkin)  WITH (delay=ns_3)
sy2 = $SDTFF( clk,  clkin,VDD,VDD) => ( sclkin,Nsclkin)  WITH (delay=ns_3)
sy3 = $SDTFF(Nclk,kdatain,VDD,VDD) => ( datain, Ndatain) WITH (delay=ns_3)
sy4 = $SDTFF( clk, datain,VDD,VDD) => (sdatain,Nsdatain) WITH (delay=ns_3)

!------------------ decode the addresses ----------------------------------

in2 = $SGate1(kcon_rd)  => Nkcon_rd  WITH (delay=ns_3,OP=NAND)
in3 = $SGate1(kdata_rd) => Nkdata_rd WITH (delay=ns_1,OP=INV)
in4 = $SGate1(kdata_wt) => Nkdata_wt WITH (delay=ns_1,OP=INV)

!------------------- the ktxint bit ---------------------------------------

tx1 = $SGate1(stx) => Nstx WITH (delay=1,OP=INV)
tx3 = $SDTFF(Nkdata_wt,VSS,Nstx,enable) => (txint,Ntxint) WITH (delay=ns_3)

!------------------- synchronise the txint --------------------------------

st1 = $SDTFF(clk,txint,VDD,enable) => (stxint,Nstxint) WITH (delay=ns_3)
st2 = $SGate2(stxint,txint) => ktxint WITH (delay=ns_1,OP=OR)

!------------------- the rxint bit ----------------------------------------

nr2 = $SGate2(kdata_rd,Nenable) => Nclrrx WITH (delay=ns_2,OP=NOR)
df2 = $SDTFF(srx,   VDD,VDD,Nclrrx) => (rxint,Nrxint) WITH (delay=ns_3)

!------------------- synchronise the rxint --------------------------------

sr1 = $SDTFF(clk,rxint,VDD,enable) => (srxint,Nsrxint) WITH (delay=ns_3)
sr2 = $SGate2(srxint,rxint) => krxint WITH (delay=ns_1,OP=OR)

!------------------- the control bits -------------------------------------

in5 = $SGate1(reset) => Nreset WITH (delay=ns_1,OP=INV)

df3 = $SDTFF(kcon_wt,data[0],VDD,Nreset) => (cclkoe,Ncclkoe)   WITH (delay=ns_3)
df4 = $SDTFF(kcon_wt,data[1],VDD,Nreset) => (cdataoe,Ncdataoe) WITH (delay=ns_3)
df5 = $SDTFF(kcon_wt,data[3],VDD,Nreset) => (enable,Nenable) WITH (delay=ns_3)

!------------------- mux rxpar with t16 for test --------------------------

xmn = $SMux(test[2],ship[9],t16) => rxpar WITH (delay=ns_3)

!------------------- the staticising latch --------------------------------

sz0 = $SDTFF(kcon_rd,sclkin ,VDD,VDD) => (sz[0],Nsz[0]) WITH (delay=ns_1)
sz1 = $SDTFF(kcon_rd,sdatain,VDD,VDD) => (sz[1],Nsz[1]) WITH (delay=ns_1)
sz2 = $SDTFF(kcon_rd,rxpar  ,VDD,VDD) => (sz[2],Nsz[2]) WITH (delay=ns_1)
sz3 = $SDTFF(kcon_rd,enable ,VDD,VDD) => (sz[3],Nsz[3]) WITH (delay=ns_1)
sz4 = $SDTFF(kcon_rd,rxb    ,VDD,VDD) => (sz[4],Nsz[4]) WITH (delay=ns_1)
sz5 = $SDTFF(kcon_rd,krxint ,VDD,VDD) => (sz[5],Nsz[5]) WITH (delay=ns_1)
sz6 = $SDTFF(kcon_rd,txb    ,VDD,VDD) => (sz[6],Nsz[6]) WITH (delay=ns_1)
sz7 = $SDTFF(kcon_rd,ktxint ,VDD,VDD) => (sz[7],Nsz[7]) WITH (delay=ns_1)

!------------------- the status register ----------------------------------

bf0 = $SBuff(sz[0],Nkcon_rd)   => data[0]   WITH (delay=ns_2)
bf1 = $SBuff(sz[1],Nkcon_rd)   => data[1]   WITH (delay=ns_2)
bf2 = $SBuff(sz[2],Nkcon_rd)   => data[2]   WITH (delay=ns_2)
bf3 = $SBuff(sz[3],Nkcon_rd)   => data[3]   WITH (delay=ns_2)
bf4 = $SBuff(sz[4],Nkcon_rd)   => data[4]   WITH (delay=ns_2)
bf5 = $SBuff(sz[5],Nkcon_rd)   => data[5]   WITH (delay=ns_2)
bf6 = $SBuff(sz[6],Nkcon_rd)   => data[6]   WITH (delay=ns_2)
bf7 = $SBuff(sz[7],Nkcon_rd)   => data[7]   WITH (delay=ns_2)

!------------------- the receive shift register ---------------------------

shan = $SGate2(rxb,kclkin) => clip WITH (delay=ns_3,OP=AND)
 
ship0 = $SDTFF(clip,ship[1] ,VDD,VDD) => (ship[0] ,Nship[0])  WITH (delay=ns_3)
ship1 = $SDTFF(clip,ship[2] ,VDD,VDD) => (ship[1] ,Nship[1])  WITH (delay=ns_3)
ship2 = $SDTFF(clip,ship[3] ,VDD,VDD) => (ship[2] ,Nship[2])  WITH (delay=ns_3)
ship3 = $SDTFF(clip,ship[4] ,VDD,VDD) => (ship[3] ,Nship[3])  WITH (delay=ns_3)
ship4 = $SDTFF(clip,ship[5] ,VDD,VDD) => (ship[4] ,Nship[4])  WITH (delay=ns_3)
ship5 = $SDTFF(clip,ship[6] ,VDD,VDD) => (ship[5] ,Nship[5])  WITH (delay=ns_3)
ship6 = $SDTFF(clip,ship[7] ,VDD,VDD) => (ship[6] ,Nship[6])  WITH (delay=ns_3)
ship7 = $SDTFF(clip,ship[8] ,VDD,VDD) => (ship[7] ,Nship[7])  WITH (delay=ns_3)
ship8 = $SDTFF(clip,ship[9] ,VDD,VDD) => (ship[8] ,Nship[8])  WITH (delay=ns_3)
ship9 = $SDTFF(clip,ship[10],VDD,VDD) => (ship[9] ,Nship[9])  WITH (delay=ns_3)
shipA = $SDTFF(clip,kdatain ,VDD,VDD) => (ship[10],Nship[10]) WITH (delay=ns_3)

!------------------- the read data buffer --------------------------------

rb0 = $SBuff(ship[1],Nkdata_rd) => data[0] WITH (delay=ns_3)
rb1 = $SBuff(ship[2],Nkdata_rd) => data[1] WITH (delay=ns_3)
rb2 = $SBuff(ship[3],Nkdata_rd) => data[2] WITH (delay=ns_3)
rb3 = $SBuff(ship[4],Nkdata_rd) => data[3] WITH (delay=ns_3)
rb4 = $SBuff(ship[5],Nkdata_rd) => data[4] WITH (delay=ns_3)
rb5 = $SBuff(ship[6],Nkdata_rd) => data[5] WITH (delay=ns_3)
rb6 = $SBuff(ship[7],Nkdata_rd) => data[6] WITH (delay=ns_3)
rb7 = $SBuff(ship[8],Nkdata_rd) => data[7] WITH (delay=ns_3)

!------------------- the transmit shift register -------------------------

shinv = $SGate1(kclkin)        => Nkclkin WITH (delay=ns_1,OP=INV)
shan2 = $SGate2(txb,Nkclkin)   => clop    WITH (delay=ns_3,OP=AND)

shops = $SDTFF(clop,shop[0] ,VDD,Nkdata_wt) => (Ndataoe ,dataoe)    WITH (delay=ns_3)
shop0 = $SDTFF(clop,shop[1] ,VDD,Nkdata_wt) => (shop[0] ,Nshop[0])  WITH (delay=ns_3)
shop1 = $SDTFF(clop,shop[2] ,Np[0],Nc[0]) => (shop[1] ,Nshop[1])  WITH (delay=ns_3)
shop2 = $SDTFF(clop,shop[3] ,Np[1],Nc[1]) => (shop[2] ,Nshop[2])  WITH (delay=ns_3)
shop3 = $SDTFF(clop,shop[4] ,Np[2],Nc[2]) => (shop[3] ,Nshop[3])  WITH (delay=ns_3)
shop4 = $SDTFF(clop,shop[5] ,Np[3],Nc[3]) => (shop[4] ,Nshop[4])  WITH (delay=ns_3)
shop5 = $SDTFF(clop,shop[6] ,Np[4],Nc[4]) => (shop[5] ,Nshop[5])  WITH (delay=ns_3)
shop6 = $SDTFF(clop,shop[7] ,Np[5],Nc[5]) => (shop[6] ,Nshop[6])  WITH (delay=ns_3)
shop7 = $SDTFF(clop,shop[8] ,Np[6],Nc[6]) => (shop[7] ,Nshop[7])  WITH (delay=ns_3)
shop8 = $SDTFF(clop,shop[9] ,Np[7],Nc[7]) => (shop[8] ,Nshop[8])  WITH (delay=ns_3)
shop9 = $SDTFF(clop,VDD     ,Nppar,Ncpar) => (shop[9] ,Nshop[9])  WITH (delay=ns_3)

!------------------- the preload logic ---------------------------------

p0 = $SGate2(kdata_wt,data[0]) => Np[0] WITH (delay=ns_2,OP=NAND)
p1 = $SGate2(kdata_wt,data[1]) => Np[1] WITH (delay=ns_2,OP=NAND)
p2 = $SGate2(kdata_wt,data[2]) => Np[2] WITH (delay=ns_2,OP=NAND)
p3 = $SGate2(kdata_wt,data[3]) => Np[3] WITH (delay=ns_2,OP=NAND)
p4 = $SGate2(kdata_wt,data[4]) => Np[4] WITH (delay=ns_2,OP=NAND)
p5 = $SGate2(kdata_wt,data[5]) => Np[5] WITH (delay=ns_2,OP=NAND)
p6 = $SGate2(kdata_wt,data[6]) => Np[6] WITH (delay=ns_2,OP=NAND)
p7 = $SGate2(kdata_wt,data[7]) => Np[7] WITH (delay=ns_2,OP=NAND)

c0 = $SGate2(Nkdata_wt,data[0]) => Nc[0] WITH (delay=ns_2,OP=OR)
c1 = $SGate2(Nkdata_wt,data[1]) => Nc[1] WITH (delay=ns_2,OP=OR)
c2 = $SGate2(Nkdata_wt,data[2]) => Nc[2] WITH (delay=ns_2,OP=OR)
c3 = $SGate2(Nkdata_wt,data[3]) => Nc[3] WITH (delay=ns_2,OP=OR)
c4 = $SGate2(Nkdata_wt,data[4]) => Nc[4] WITH (delay=ns_2,OP=OR)
c5 = $SGate2(Nkdata_wt,data[5]) => Nc[5] WITH (delay=ns_2,OP=OR)
c6 = $SGate2(Nkdata_wt,data[6]) => Nc[6] WITH (delay=ns_2,OP=OR)
c7 = $SGate2(Nkdata_wt,data[7]) => Nc[7] WITH (delay=ns_2,OP=OR)

!-------------------- generate the tx parity --------------------------

x0 = $SGate2(data[0],data[1]) => x0     WITH (delay=ns_2,OP=XOR)
x1 = $SGate2(data[2],data[3]) => x1     WITH (delay=ns_2,OP=XOR)
x2 = $SGate2(data[4],data[5]) => x2     WITH (delay=ns_2,OP=XOR)
x3 = $SGate2(data[6],data[7]) => x3     WITH (delay=ns_2,OP=XOR)
x4 = $SGate2(x0,x1)           => x4     WITH (delay=ns_2,OP=XOR)
x5 = $SGate2(x2,x3)           => x5     WITH (delay=ns_2,OP=XOR)
x6 = $SGate2(x4,x5)           => txpar  WITH (delay=ns_2,OP=NXOR)
x7 = $SGate2(kdata_wt,txpar)    => Nppar  WITH (delay=ns_2,OP=NAND)
x8 = $SGate2(Nkdata_wt,txpar)   => Ncpar  WITH (delay=ns_2,OP=OR)

END {KBD}
